"""
大麦网App抢票核心模块
处理订单提交、座位选择、支付等核心流程（移动端版本）
"""

import time
import logging
import random
from typing import Dict, Any, List, Optional
from utils.mobile_driver_base import MobileDriverBase
from utils.common_utils import (
    random_sleep,
    play_notification_sound,
    show_notification,
    generate_screenshot_filename,
)


class DamaiTicketGrabber:
    """大麦网App抢票核心处理类"""

    def __init__(self, mobile_driver: MobileDriverBase, config: Dict[str, Any]):
        self.driver = mobile_driver
        self.config = config
        self.logger = logging.getLogger("DamaiTicketGrabber")
        self.retry_count = 0
        self.max_retry = config.get("retry", {}).get("max_retry_times", 50)

    def start_grabbing(self) -> bool:
        """开始抢票流程"""
        try:
            self.logger.info("开始抢票流程")

            # 持续尝试抢票
            while self.retry_count < self.max_retry:
                self.retry_count += 1
                self.logger.info(f"第 {self.retry_count} 次尝试抢票")

                try:
                    # 检查是否进入了确认订单页面
                    if self._is_on_confirm_page():
                        self.logger.info("已进入确认订单页面")
                        return self._handle_confirm_order()

                    # 检查是否需要选择座位
                    if self._need_seat_selection():
                        self.logger.info("需要选择座位")
                        if not self._select_seats():
                            continue

                    # 检查购买按钮状态并点击
                    if self._try_click_buy_button():
                        # 等待页面跳转
                        time.sleep(3)
                        continue

                    # 检查是否有错误提示
                    error_msg = self._get_error_message()
                    if error_msg:
                        self.logger.warning(f"发现错误提示: {error_msg}")
                        if any(
                            keyword in error_msg
                            for keyword in [
                                "库存不足",
                                "已售罄",
                                "暂无库存",
                                "票已售完",
                            ]
                        ):
                            self.logger.error("票品已售罄，停止抢票")
                            return False

                    # 随机等待后重试
                    retry_interval = self.config.get("retry", {}).get(
                        "retry_interval", 0.5
                    )
                    random_sleep(retry_interval - 0.2, retry_interval + 0.2)

                except Exception as e:
                    self.logger.warning(f"第 {self.retry_count} 次尝试出错: {e}")
                    continue

            self.logger.error(f"已达到最大重试次数 {self.max_retry}，抢票失败")
            return False

        except Exception as e:
            self.logger.error(f"抢票流程异常: {e}")
            return False

    def _is_on_confirm_page(self) -> bool:
        """检查是否在确认订单页面"""
        try:
            # 检查确认页面的特征元素
            indicators = [
                {"textContains": "确认订单"},
                {"textContains": "提交订单"},
                {"textContains": "订单信息"},
                {"textContains": "实名制"},
                {"textContains": "收货信息"},
                {"resourceId": "cn.damai:id/confirm_order"},
                {"text": "确认并支付"},
            ]

            for indicator in indicators:
                if self.driver.find_element(**indicator):
                    return True

            return False

        except Exception:
            return False
            return False

    def _need_seat_selection(self) -> bool:
        """检查是否需要选择座位"""
        try:
            # 查找座位选择相关元素
            seat_indicators = [
                {"textContains": "选择座位"},
                {"textContains": "座位图"},
                {"textContains": "选座"},
                {"resourceId": "cn.damai:id/seat_map"},
                {"className": "android.webkit.WebView"},  # 座位图通常是WebView
                {"description": "座位选择"},
            ]

            for indicator in seat_indicators:
                if self.driver.find_element(**indicator):
                    return True

            return False

        except Exception:
            return False

    def _select_seats(self) -> bool:
        """选择座位"""
        try:
            self.logger.info("开始选择座位")

            # 等待座位图加载
            time.sleep(3)

            # 尝试自动选座
            if self._try_auto_seat_selection():
                return True

            # 手动选择座位
            if self._try_manual_seat_selection():
                return True

            # 如果有推荐座位按钮
            if self._try_recommended_seats():
                return True

            self.logger.warning("座位选择失败")
            return False

        except Exception as e:
            self.logger.error(f"选择座位出错: {e}")
            return False

    def _try_auto_seat_selection(self) -> bool:
        """尝试自动选座"""
        try:
            auto_select_options = [
                {"text": "自动选座"},
                {"text": "推荐座位"},
                {"text": "为我推荐"},
                {"textContains": "自动"},
                {"resourceId": "cn.damai:id/auto_select"},
                {"description": "自动选座"},
            ]

            for option in auto_select_options:
                if self.driver.click_element(timeout=2, **option):
                    self.logger.info("找到自动选座按钮")
                    time.sleep(2)

                    # 检查是否选座成功
                    if self._check_seats_selected():
                        self.logger.info("自动选座成功")
                        return True

            return False

        except Exception:
            return False

    def _try_manual_seat_selection(self) -> bool:
        """尝试手动选择座位"""
        try:
            # 查找可选择的座位元素
            available_seat_indicators = [
                {"className": "android.view.View", "textContains": "可选"},
                {"description": "可选座位"},
                {"resourceId": "cn.damai:id/available_seat"},
            ]

            ticket_num = self.config.get("ticket", {}).get("ticket_num", 1)

            for indicator in available_seat_indicators:
                available_seats = self.driver.find_elements(**indicator)
                if available_seats:
                    seats_to_select = min(ticket_num, len(available_seats))
                    self.logger.info(
                        f"找到 {len(available_seats)} 个可选座位，需要选择 {seats_to_select} 个"
                    )

                    # 选择所需数量的座位
                    for i in range(seats_to_select):
                        try:
                            available_seats[i].click()
                            random_sleep(0.3, 0.8)
                        except Exception as e:
                            self.logger.warning(f"点击座位 {i} 失败: {e}")

                    # 检查是否选座成功
                    return self._check_seats_selected()

            return False

        except Exception as e:
            self.logger.error(f"手动选座失败: {e}")
            return False

    def _try_recommended_seats(self) -> bool:
        """尝试推荐座位"""
        try:
            recommended_options = [
                {"text": "推荐"},
                {"textContains": "推荐座位"},
                {"resourceId": "cn.damai:id/recommend_seat"},
                {"description": "推荐座位"},
            ]

            for option in recommended_options:
                if self.driver.click_element(timeout=2, **option):
                    time.sleep(2)
                    return self._check_seats_selected()

            return False

        except Exception:
            return False

    def _check_seats_selected(self) -> bool:
        """检查座位是否选择成功"""
        try:
            # 查找确认选座按钮
            confirm_options = [
                {"text": "确认选座"},
                {"text": "确认座位"},
                {"text": "下一步"},
                {"text": "确定"},
                {"resourceId": "cn.damai:id/confirm_seat"},
            ]

            for option in confirm_options:
                if self.driver.click_element(timeout=2, **option):
                    self.logger.info("座位选择成功，点击确认")
                    time.sleep(2)
                    return True

            # 检查页面是否有选座成功的标识
            success_indicators = [
                {"textContains": "已选座位"},
                {"textContains": "座位确认"},
                {"text": "继续购买"},
            ]

            for indicator in success_indicators:
                if self.driver.find_element(**indicator):
                    return True

            return True  # 如果找不到确认按钮，假设选座成功

        except Exception:
            return False

    def _try_click_buy_button(self) -> bool:
        """尝试点击购买按钮"""
        try:
            buy_options = [
                {"text": "立即购买"},
                {"text": "立即抢购"},
                {"text": "立即预订"},
                {"text": "马上抢"},
                {"textContains": "购买"},
                {"textContains": "抢购"},
                {"resourceId": "cn.damai:id/buy_btn"},
                {"className": "android.widget.Button", "textContains": "立即"},
            ]

            for option in buy_options:
                if self.driver.click_element(timeout=1, **option):
                    self.logger.info("成功点击购买按钮")
                    return True

            return False

        except Exception as e:
            self.logger.error(f"点击购买按钮失败: {e}")
            return False

    def _get_error_message(self) -> Optional[str]:
        """获取错误提示信息"""
        try:
            error_indicators = [
                {"textContains": "库存不足"},
                {"textContains": "已售罄"},
                {"textContains": "暂无库存"},
                {"textContains": "票已售完"},
                {"textContains": "抢购失败"},
                {"textContains": "网络错误"},
                {"className": "android.widget.TextView", "textContains": "失败"},
            ]

            for indicator in error_indicators:
                error_element = self.driver.find_element(**indicator)
                if error_element:
                    text = self.driver.get_text(**indicator)
                    if text:
                        return text.strip()

            return None

        except Exception:
            return None

    def _handle_confirm_order(self) -> bool:
        """处理确认订单页面"""
        try:
            self.logger.info("处理确认订单页面")

            # 填写实名制信息
            if not self._fill_real_name_info():
                self.logger.error("填写实名制信息失败")
                return False

            # 选择配送方式（如果需要）
            self._select_delivery_method()

            # 最终确认并提交订单
            if self._submit_final_order():
                self.logger.info("订单提交成功！")

                # 发送通知
                self._send_success_notification()

                # 截图保存
                screenshot_path = generate_screenshot_filename()
                self.driver.screenshot(screenshot_path)
                self.logger.info(f"成功截图保存至: {screenshot_path}")

                return True

            return False

        except Exception as e:
            self.logger.error(f"处理确认订单页面失败: {e}")
            return False

    def _fill_real_name_info(self) -> bool:
        """填写实名制信息"""
        try:
            user_config = self.config.get("user", {})
            real_name = user_config.get("real_name", "")
            id_card = user_config.get("id_card", "")
            phone = user_config.get("phone", "")

            # 填写姓名
            name_selectors = [
                {"text": "请输入姓名"},
                {"textContains": "姓名"},
                {"resourceId": "cn.damai:id/real_name"},
                {"description": "姓名输入框"},
            ]

            for selector in name_selectors:
                if self.driver.input_text(real_name, **selector) and real_name:
                    self.logger.info(f"已填写姓名: {real_name}")
                    break

            # 填写身份证号
            id_selectors = [
                {"text": "请输入身份证号"},
                {"textContains": "身份证"},
                {"resourceId": "cn.damai:id/id_number"},
                {"description": "身份证号输入框"},
            ]

            for selector in id_selectors:
                if self.driver.input_text(id_card, **selector) and id_card:
                    self.logger.info("已填写身份证号")
                    break

            # 填写手机号
            phone_selectors = [
                {"text": "请输入手机号"},
                {"textContains": "手机号"},
                {"resourceId": "cn.damai:id/mobile"},
                {"description": "手机号输入框"},
            ]

            for selector in phone_selectors:
                if self.driver.input_text(phone, **selector) and phone:
                    self.logger.info(f"已填写手机号: {phone}")
                    break

            return True

        except Exception as e:
            self.logger.warning(f"填写实名制信息出错: {e}")
            return True  # 即使填写失败也继续流程

    def _select_delivery_method(self) -> None:
        """选择配送方式"""
        try:
            # 优先选择电子票
            electronic_options = [
                {"text": "电子票"},
                {"textContains": "电子"},
                {"resourceId": "cn.damai:id/electronic_ticket"},
                {"description": "电子票"},
            ]

            for option in electronic_options:
                if self.driver.click_element(timeout=3, **option):
                    self.logger.info("已选择电子票配送")
                    return

            # 选择快递配送
            express_options = [
                {"text": "快递配送"},
                {"textContains": "快递"},
                {"resourceId": "cn.damai:id/express_delivery"},
            ]

            for option in express_options:
                if self.driver.click_element(timeout=3, **option):
                    self.logger.info("已选择快递配送")
                    return

        except Exception:
            self.logger.info("未找到配送方式选择，跳过")

    def _submit_final_order(self) -> bool:
        """提交最终订单"""
        try:
            # 查找提交订单按钮
            submit_options = [
                {"text": "提交订单"},
                {"text": "确认订单"},
                {"text": "立即支付"},
                {"text": "确认并支付"},
                {"textContains": "提交"},
                {"resourceId": "cn.damai:id/submit_order"},
                {"className": "android.widget.Button", "textContains": "确认"},
            ]

            for option in submit_options:
                if self.driver.find_element(**option):
                    # 同意用户协议（如果存在）
                    self._agree_terms()

                    # 点击提交
                    if self.driver.click_element(timeout=2, **option):
                        self.logger.info("已点击提交订单按钮")

                        # 等待订单提交结果
                        time.sleep(5)

                        # 检查是否提交成功
                        if self._check_order_submitted():
                            return True

            return False

        except Exception as e:
            self.logger.error(f"提交订单失败: {e}")
            return False

    def _agree_terms(self) -> None:
        """同意用户协议"""
        try:
            agreement_options = [
                {"textContains": "同意"},
                {"text": "我已阅读并同意"},
                {"resourceId": "cn.damai:id/agree_checkbox"},
                {"className": "android.widget.CheckBox"},
            ]

            for option in agreement_options:
                if self.driver.click_element(timeout=1, **option):
                    self.logger.info("已同意用户协议")
                    break

        except Exception:
            pass  # 忽略协议勾选失败

    def _check_order_submitted(self) -> bool:
        """检查订单是否提交成功"""
        try:
            # 检查成功页面标识
            success_indicators = [
                {"textContains": "订单提交成功"},
                {"textContains": "购买成功"},
                {"textContains": "支付"},
                {"textContains": "订单号"},
                {"text": "去支付"},
                {"resourceId": "cn.damai:id/order_success"},
            ]

            for indicator in success_indicators:
                if self.driver.find_element(**indicator):
                    return True

            return False

        except Exception:
            return False

    def _send_success_notification(self) -> None:
        """发送成功通知"""
        try:
            config = self.config.get("notification", {})

            if config.get("enable_sound", True):
                play_notification_sound()

            if config.get("enable_popup", True):
                show_notification(
                    "抢票成功！",
                    f"成功抢到 {self.config.get('ticket', {}).get('event_name', '演出')} 的票！",
                )

        except Exception as e:
            self.logger.warning(f"发送通知失败: {e}")
